/**
* 操作 文件 目录 的工具类
**/

#include <util.h>
#include <sys/stat.h>
/**
 * 删除指定路径的目录
 * @param path 要删除的目录路径
 * @return 0 表示成功删除，-1 表示删除失败
 */
int rmDir(const char *path){
    if (path == NULL)return 0;
    fs::path dir_path(path);  // 当前目录
    // 检查路径是否存在
    if (!fs::exists(dir_path))return 0;
        try {
            uintmax_t numRemoved = fs::remove_all(dir_path);
            cout << "成功删除 " << numRemoved << " 个文件或目录" << endl;
        } catch (const fs::filesystem_error& e) {
            cerr << "删除目录失败 : " << e.what() << endl;
            return -1;
        }
    return 0;
}
/**
 * 创建指定路径的目录
 * @param path 要创建的目录路径
 * @return 0 表示成功创建，-1 表示创建失败
 */
int mkDir(const char *path){
// 定义要递归创建的目录路径
    fs::path dir_path(path);  // 当前目录
 // 使用std::filesystem::exists来检查文件夹是否存在
    if (fs::exists(dir_path))return -1;
    try {
        // 递归创建目录
        if (fs::create_directories(dir_path)) {
            cout << "创建目录成功: " << dir_path << endl;
            return 0;
        } else {
            cout << "创建目录失败: " << dir_path << endl;
            return -1;
        }
    } catch (const fs::filesystem_error& e) {
        // 捕获并输出创建目录时可能出现的错误
        cerr << "创建目录异常: " << e.what() << endl;
        return -1;
    }
    return 0;
}
/**
 * 列出指定目录下的所有文件
 * @param path 要列出文件的目录路径
 * @param files 用于存储文件路径的向量
 * @return 0 表示成功列出文件，-1 表示列出文件失败
 */
int listFilesInDirectory(const string& path,vector<string>& files) {
    try {
            fs::path dir_path(path);  // 当前目录
            if (!fs::exists(dir_path)) return -1;
            if (!fs::is_directory(dir_path)) return -1;
            for (const auto& entry : fs::directory_iterator(dir_path)) {
                if (entry.is_directory()) {
                    listFilesInDirectory(entry.path().string(),files);
                }else{
                    files.push_back(entry.path().filename().string());
                }
            }
    } catch (const fs::filesystem_error& e) {
        cerr << "文件系统错误: " << e.what() << endl;
        return -1;
    }
    return 0;
}
/**
* 使用当前时间戳创建一个临时目录
* @param parentDir 父目录路径
* @param subdirectory 子目录路径
* @return 0 表示成功创建，-1 表示创建失败
*/
int mkDirTmp(string parentDir,string& subdirectory){
    // 休眠 1 秒
    this_thread::sleep_for(chrono::seconds(1));
    // 获取当前时间
    time_t now = time(nullptr);
    // 将当前时间转换为本地时间
    tm *localTime = localtime(&now);
    // 使用 std::put_time 格式化时间
    char buffer[32];
    // 使用 std::strftime 格式化时间
    strftime(buffer, sizeof(buffer), "%Y-%m-%d-%H-%M-%S", localTime);
    // 使用 string 的构造函数将字符数组转换为 string 对象
    string strTime(buffer);
    // 假设你想要检查的文件夹路径
    subdirectory = parentDir+"/" + strTime;
    return mkDir(subdirectory.c_str());
}
/**
* 复制文件 如果目标文件不存在 则复制 如果存在 则不复制
* @param source 源文件路径
* @param destination 目标文件路径
* @return true 表示复制成功，false 表示复制失败
*/
int copyFileIfNotExists(const char* source, const char* destination) {
    fs::path fin = source;  // 替换为实际存在的文件路径
    fs::path fout = destination;
    try {
        // 检查源文件是否存在
        if (!fs::exists(fin)) {
            cerr << "源文件不存在: " << source << endl;
            return -1;
        }
        // 检查目标文件是否存在
        if (fs::exists(fout)) {
            cerr << "目标文件已存在: " << destination << endl;
            return 1;
        }
        // 检查目标目录是否存在，不存在则创建
        if (!fs::exists(fout.parent_path())) {
            fs::create_directories(fout.parent_path());
        }
        // 复制文件
        fs::copy_file(fin, fout,fs::copy_options::overwrite_existing);
       // 获取源文件权限，使用 static_cast 显式转换为 mode_t 类型
        mode_t mode = static_cast<mode_t>(fs::status(fin).permissions());
        // 设置目标文件权限
        if (chmod(destination,mode) != 0) {
           cerr << "设置文件权限失败" << endl;
        } else {
           cout << "文件复制成功，权限已保留 : " <<source<< endl;
        }
        return 2;
    } catch (const fs::filesystem_error& e) {
        cerr << "文件复制出错: " << e.what() << endl;
        return -1;
    }
}
/**
* 获取指定路径的文件名
* @param filePath 文件路径
* @return 文件名
*/
string getFileName(const string& filePath) {
    size_t lastSlash = filePath.find_last_of("/\\");
    if (lastSlash != string::npos) {
        return filePath.substr(lastSlash + 1);
    }
    return filePath;
}


/**
* 将字符串写入文件
* @param fileName 文件名
* @param content 文件内容
* @return 0 表示成功，-1 表示失败
*/
int stringWriteFile(const char *fileName,string content){
    // 获取文件路径
    filesystem::path filePath(fileName);
    // 获取文件所在目录
    filesystem::path directory = filePath.parent_path();

    // 检查目录是否存在，如果不存在则创建
    if (!filesystem::exists(directory)) {
        if (!filesystem::create_directories(directory)) {
            cerr << "无法创建目录: " << directory << endl;
            return -1;
        }
    }

    // 创建 Dockerfile 并写入内容
    ofstream outFile(fileName,ios::out | ios::binary);
    // 检查文件是否成功打开
    if (!outFile.is_open()) {
        cerr << "无法打开文件！" << fileName<<endl;
        return -1;
    }
    // 设置locale为UTF-8
    outFile.imbue(locale(outFile.getloc(), new codecvt_utf8<wchar_t>));
    // 写入字符到文件
    outFile << content;
    // 关闭文件
    outFile.close();
    return 0;
}

/**
* 分割字符串
* @param str 字符串
* @param delimiter 分隔符
* @return 分割后的字符串数组
*/
vector<string> string_split(const string& str,const char* delimiter) {
    vector<string> tokens;
    size_t start = 0, end = 0;
    while ((end = str.find(delimiter, start)) != string::npos) {
        tokens.push_back(str.substr(start, end - start));
        start = end + 1;
    }
    tokens.push_back(str.substr(start));
    return tokens;
}




